/*
	Copyright (C) 2010 2011 Rémi Thebault

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <procycle/atomtask.h>
#include <procycle/cycle.h>
#include <procycle/link.h>

namespace PC {

AtomTask::AtomTask(Cycle* cycle, MacroTask* parent)
:	Task(cycle, parent)
{
	m_cycle->connectTask(this);
}


AtomTask::AtomTask(Task* other)
:	Task(other)
{
	m_cycle->connectTask(this);
}

AtomTask::~AtomTask() {
	m_cycle->disconnectTask(this);
}


int
AtomTask::setNum(int current) {
	m_num = current;
	return current+1;
}



void AtomTask::setLength(int length) {
	m_length = length;
	m_cycle->schedule();
}



void AtomTask::forwSchedule(Link *inLink) {
	if (inLink != 0) {
		switch(inLink->type()) {
		case Link::TYPE_FS:
		case Link::TYPE_SS:
			m_fTmps.append(inLink->timeTo());
			break;
		case Link::TYPE_SF:
		case Link::TYPE_FF:
			m_fTmps.append(parent()->start());
			break;
		}
		m_start = maxFTmp();
	}
	else if (isBegin()) {
		m_start = parent()->start();
	}
	m_finish = m_start + m_length;
	foreach(Link* l, m_outLinks) {
		l->taskTo()->forwSchedule(l);
	}
}


void AtomTask::backwSchedule(Link* outLink) {
	if (outLink != 0) {
		switch(outLink->type()) {
		case Link::TYPE_FS:
		case Link::TYPE_FF:
			m_bTmps.append(outLink->lateTimeFrom());
			break;
		case Link::TYPE_SS:
		case Link::TYPE_SF:
			m_bTmps.append(parent()->lateFinish());
			break;
		}
		m_lateFinish = minBTmp();
	}
	else if (isEnd()) {
		m_lateFinish = parent()->lateFinish();
	}

	m_lateStart = m_lateFinish - m_length;

	foreach(Link* l, m_inLinks) {
		l->taskFrom()->backwSchedule(l);
	}
}



void
AtomTask::loadFromElement(const QDomElement& element) {
	Task::loadFromElement(element);
	bool ok;
	m_length = element.attribute("length").toInt(&ok);
	if (!ok) {
		throw XmlFormatError();
	}
}


QDomElement
AtomTask::saveToElement(QDomDocument& doc) const {
	QDomElement element = Task::saveToElement(doc);
	element.setAttribute("length", m_length);
	return element;
}

}
